﻿#region Header
/********************************************************           
 * ResponseData        
 *                                                         
 * Author:  Richard Barclay  (phphanatic at gmail dot com) 
 * 
 * Copyright: 2009 Richard Barclay
 * 
 * License: GNU General Public License (GPL)
 *     
 * This file is part of the Intergr8.GoogleVisualization library.
 *
 *   The Intergr8.GoogleVisualization library is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *  Intergr8.GoogleVisualization library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Intergr8.GoogleVisualization library.  If not, see <http://www.gnu.org/licenses/>.
 *                                                         
 * Purpose:  Wraps the dataset to be returned and mamages all the DataTable to JSON conversion
 *                                                         
 * Usage:                                                  
 *      Populate with response datatable  and pass to  the ResponseMessage object
 *     for inclusion in the final package
 ********************************************************/
#endregion



namespace Intergr8.GoogleVisualization
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;

    using Intergr8.GoogleVisualization.Interfaces;


    /// <summary>
    /// Manages the Data that will be returned for a given request
    /// </summary>
    public class ResponseData : IResponseData
    {
        private const string DEFAULT_DATATABLE_TABLENAME = "RAWDATA";

        #region Attributes
        /// <summary>
		/// The data to be converted to JSON format 
		/// </summary>
        private DataTable _data = null;

        /// <summary>
        /// A string representation of the converted datatable
        /// </summary>
        private string _outputData = "";
        /// <summary>
        /// Flag that the conversion has already been done for this DataTable
        /// </summary>
        private bool _converted = false;
        #endregion

        #region Factory Creation Methods
        /// <summary>
        /// Create a ResponseData instance with a preformatted JSON data string
        /// </summary>
        /// <param name="jsonDataTable"></param>
        /// <returns></returns>
        public static IResponseData GenerateResponseData(string jsonDataTable)
        {
            IResponseData resp = new ResponseData(jsonDataTable);
            return resp;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static IResponseData GenerateResponseData(DataTable data)
        {
            IResponseData resp = new ResponseData(data);
            return resp;
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Constructor taking a Datatable object.
        /// </summary>
        /// <param name="data">DataTable object containing the data to be converted</param>
        private ResponseData(DataTable data)
        {
            _data = data;

            // The data table must have a name, if not, set the default
            if (_data.TableName.Length == 0)
            {
                _data.TableName = DEFAULT_DATATABLE_TABLENAME;
            }

            // conversion is required for this constructor type
            _converted = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        private ResponseData(string data)
        {
            // set the output data directly
            _outputData = data;

            //no conversion is required
            _converted = true;
        }

        #endregion


        #region Business Methods

        /// <summary>
        /// Apply the query to the data and update the internal data appropriately.
        /// </summary>
        /// <param name="view"></param>
        public void Filter(ITQ query)
        {
            try
            {
                // can only do the filtering if we are working with a DataTable. 
                // If we have a completed JSON data string then just avoid this bit for the moment
                if (this._data != null)
                {
                    DataView view = query.Query;
                    DataTable results = new DataTable();

                    view.Table = _data;

                    results = view.ToTable(_data.TableName);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        /// Hashcode of the JSON data string
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            if (_outputData != null)
            {
                return _outputData.GetHashCode();
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public DataTable Data
        {
            get { return _data; }
        }

        /// <summary>
        /// Return the Data content in a JSON format
        /// TODO: If its not already in a valid JSON fomat, use a Formatter to control conversion from intialisation structure to JSON format
        /// </summary>
        public string toJSON
        {
            get
            {
                if (_converted == false)
                {
                    System.IO.StreamReader sr = null;
                    try
                    {
                        // Do an immediate conversion
                        Bortosky.Google.Visualization.GoogleDataTable gdt = new Bortosky.Google.Visualization.GoogleDataTable(_data);

                        using (System.IO.MemoryStream mem = new System.IO.MemoryStream())
                        {
                            gdt.WriteJson(mem);
                            mem.Position = 0;
                            sr = new System.IO.StreamReader(mem);
                            _outputData = sr.ReadToEnd();
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                    finally
                    {
                        if (sr != null)
                        {
                            sr.Close();
                        }
                    }
                }
                return _outputData;
            }
        }

        /// <summary>
        /// Return the Data content in an XML format
        /// TODO: Formatter to control conversion from intialisation structure to JSON format
        /// </summary>
        public string toXml
        {
            get {
                throw new NotImplementedException("XML Format support has not been implemented");
            }

        }

        /// <summary>
        /// 
        /// </summary>
        public string toCsv
        {
            get { 
                throw new NotImplementedException("CSV Format support has not been implemented");
            }
        }

        #endregion
    }

}
